[JAVA]面试基础

面向对象

三大基本特征:封装、继承、多态。

  • 封装:
    • 将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象的内部信息。
    • 让外部程序通过该类提供的方法来实现对内部信息的操作和访问。
  • 继承:
    • 实现代码复用的重要手段。
    • 子类可以直接访问父类的公共属性,保护属性,构造方法,父类中被子类重写的方法,可以通过super关键字调用父类的被重写方法。
    • 不能继承私有成员的变量和方法,final、static。
  • 多态:
    • 继承统一父类的多个子类执行同一个方法时出现不同的情况。
    • 主要通过重写实现。

基本的数据类型和引用类型

  • 8种数据类型:byte(8),short(166),int(32),long(64),float(32),double(64),char(16),boolean。
  • 其他类型都是引用类型:类,接口,数组,Strin等。

抽象类和接口的区别

  • 相同点:
    • 都不能被实例化,都位于继承树的顶端,用于被其他类实现和继承。
    • 接口和抽象类都可以有抽象方法,实现接口或继承抽象类都必须实现这些方法。
  • 不同点:
    • 成员变量:
      • 抽象类:可以有静态变量、常量和成员变量。
      • 接口:只能有常量。
    • 方法:
      • 抽象类:可以有普通方法和抽象方法,抽象方法必须在子类中被实现,而具体方法可以在抽象类中被实现。
      • 接口:只能包含抽象方法,所有的方法必须在实现类中被实现。
    • 构造函数:
      • 抽象类:可以有构造函数。
      • 接口:不能有构造函数。
    • 继承方式:
      • 抽象类:单继承
      • 接口:一个类可是实现多个接口。

重载和重写的区别

  • 重载:发生在一个类中,方法名相同,参数列表,返回值,访问修饰符都可以不同。
  • 重写:发生在父子类中。

    • 方法名相同,参数类型相同。
    • 子类返回类型小于等于父类方法返回类型。
    • 子类访问权限大于等于父类方法访问权限。
    • 子类抛出的异常大于等于父类抛出的异常。
  • final,private修饰的方法不能被重写,构造方法也不能重写。

final关键字

  • final可以修饰类、方法、变量。
  • final修饰类:类不可以被继承。
  • final修饰方法:该方法不能被重写。
  • final修饰变量:如果是基本变量则不能再改变,如果是应用变量则引用地址不能改变,但值可以改变。

重写equals()要重写hashCode()

  • hashCode():获取哈希吗的,eauals()比较两个对象是否相等。
  • 二者的两个约定:
    • 若两个对象相等,他们必须拥有相同的哈希码。
    • 若两个对象的哈希码相同,它们却不一定相同。
  • 也就是说equals()比较两个对象时,hashCode()一定相同。
  • hashCode()相等的两个对象equals()不一定相同。
  • 由于两者具有联动关系,所以equals()重写时,hashCode()也要重写,否则可能会出现equals()相等,hashCode()却不同的情况。

类加载过程

首先检查类是否被加载,如没有没有则按以下顺序加载。
加载,验证,准备,解析,初始化

  • 加载:
    • 类加载器通过将类的字节码从文件或网络中读取到JVM中来加载类。
    • 加载后会被存储到方法区。
  • 验证:
    • JVM会检查类的字节码是否符合Java虚拟机规范,并且是否可以安全执行。
  • 准备:
    • JVM回味类的静态变量分配内存,并设置默认值(0)。
  • 解析:
    • JVM会将类中的符号引用转换成直接引用。
    • 例如将类中的方法调用转换成实际的内存地址。
  • 初始化:
    • JVM为类的静态赋予程序中指定的值,并初始化类变量和其他资源,并执行类构造器。

String = “” 和 new String的区别

  • 当使用String = “”创建字符串常量是,Java会在常量池中查找是否已经有该字符串常量的引用。如果有直接返回该引用,没有则创建并存储在常量池中,并返回该引用。
  • 使用new时,无论常量池中是否存在,都会创建一个新的对象。
  • 使用new创建的会在堆区中分配系的内存空间,而字符串常量放在常量池中。

String StringBuffer StringBuilder

String

  • String是一个不可变类,被final修饰。
  • 效率低,复用率高。
    • 归常量池馆,可以随时从常量池调用同一个String对象。其他两个一般要转换成String对象才调用。

StringBuffer

  • 代表一个字符序列可变的字符串,可以通过insert(),append()等方法改变字符串序列。
  • 线程安全的。

StringBuilder

  • 也是一个字符序列可变的字符串。
  • 效率最高,线程不安全。

浅拷贝和深拷贝的区别

浅拷贝

  • 对于基本数据类型,会直接复制值给拷贝对象。
  • 对于引用类型,会复制对象的地址,而实际上指向的还是原来的那个对象。

深拷贝

  • 无论是基本类型还是引用类型,深拷贝会将引用类型的所有内容,全部拷贝作为一个新的对象。
  • 包括对象内部的所有成员变量,也会进行拷贝。
  • 但是其内层对象并没有进行拷贝,依然只是对象引用的复制。

Cookie Session Token

  • 一种存储在浏览器中的数据,保存在本地。
  • 每次浏览器发起请求,都会把这个cookie发给服务端,服务端可以使用cookie来识别用户。
  • cookie的缺点就是不安全,容易被窃取。

    Session

  • 一种在服务端记录用户状态的技术。
  • 当用户在应用程序认证后,服务端会为用户创建一个Session ID和会话结束时间,并将其唯一标识符存储到session ID。
  • 服务器会把Session ID和会话结束时间放入Cookie中发送给浏览器,会话结束时间就是这个Cookie的有效期。
  • 浏览器拿到Cookie后进行保存,但Cookie里面保存的不是用户名和密码,而是这个Seesion Id和有效期。
  • 浏览器再次访问就是发送这个Cookie。

Token

  • 服务器存储seesion ID过多时容易崩溃,且要互相分享。
  • JWT:
    • 用户第一次登陆后,服务器会生成一个JWT,服务器不需要保存这个JWT,只需要保存JWT签名的密文。
    • 将JWT发送给浏览器,浏览器保存JWT,每次发送时就发送JWT。
  • 与Seesion不同的是,服务器没有将Token信息存储在服务端,只是存储了一个加密密文。服务端不需要任何关于用户状态的信息。
  • 浏览器发送Token,服务端只需要将其解密并确认用户登陆就行 。